﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using System.Web.Routing;

using ERPStore.Web.Html;
using ERPStore.Web.Routing;
using ERPStore.Extensions;

using Microsoft.Practices.Unity;

using CloudSoft.Extensions;

namespace ERPStore.Diagnostics.Controllers
{
	public class DiagnosticController : Controller
	{
		public DiagnosticController(ERPStore.Services.ICacheService cacheService
			, ERPStore.Services.IScheduledTaskService taskService)
		{
			this.CacheService = cacheService;
			this.TaskService = taskService;
		}

		protected ERPStore.Services.ICacheService CacheService { get; private set; }

		protected ERPStore.Services.IScheduledTaskService TaskService { get; private set; }

		[ERPStore.Web.Controllers.ActionFilters.AuthorizeActionFilter]
		public ActionResult Index()
		{
			var cacheItemCount = CacheService.ItemCount;
			string content = string.Format("Nombre d'item en cache : {0}", cacheItemCount);

			var taskCount = TaskService.GetTaskCount();
			string taskContent = string.Format("Nombre de taches : {0}", taskCount);

			var sb = new StringBuilder();

			sb.AppendLine("<html><body>");

			sb.AppendFormat("<p>{0}</p>", content);
			sb.AppendFormat("<p>{0}</p>", taskContent);
            sb.AppendFormat("<p>Nombre de services {0}</p>", 0);

			sb.AppendLine("</body></html>");

			return Content(sb.ToString(), "text/html");
		}

		[ERPStore.Web.Controllers.ActionFilters.AuthorizeActionFilter]
		public ActionResult ShowRegistrations()
		{
			var container = GlobalConfiguration.Configuration.DependencyResolver.GetContainer();

			var sb = new StringBuilder();

			sb.AppendLine("<html><body>");
			sb.AppendFormat("<p>Nombre de services {0}</p>", container.Registrations.Count());

			sb.AppendLine("<table>");
			sb.AppendLine("<tr>");
			sb.AppendLine("<td>Name</td>");
			sb.AppendLine("<td>Registered</td>");
			sb.AppendLine("<td>MappedTo</td>");
			sb.AppendLine("<td>LifetimeManager</td>");
			sb.AppendLine("</tr>");


			foreach (var item in container.Registrations)
			{
				sb.AppendLine("<tr>");
				sb.AppendFormat("<td>{0}</td>", item.Name);
				sb.AppendFormat("<td>{0}</td>", item.RegisteredType);
				sb.AppendFormat("<td>{0}</td>", item.MappedToType);
				sb.AppendFormat("<td>{0}</td>", item.LifetimeManagerType);
				sb.AppendLine("</tr>");
			}
			sb.AppendLine("</table>");

			sb.AppendLine("</body></html>");

			return Content(sb.ToString(), "text/html");
		}

		[ERPStore.Web.Controllers.ActionFilters.AuthorizeActionFilter]
		public ActionResult ShowFilters()
		{
			var sb = new StringBuilder();

			sb.AppendLine("<html><body>");
			sb.AppendFormat("<p>Global Filters {0}</p>", GlobalFilters.Filters.Count);

			sb.AppendLine("<table>");
			sb.AppendLine("<tr>");
			sb.AppendLine("<td>Name</td>");
			sb.AppendLine("<td>Scope</td>");
			sb.AppendLine("<td>Order</td>");
			sb.AppendLine("</tr>");

			foreach (var item in GlobalFilters.Filters)
			{
				sb.AppendLine("<tr>");
				sb.AppendFormat("<td>{0}</td>", item.Instance.GetType().Name);
				sb.AppendFormat("<td>{0}</td>", item.Scope);
				sb.AppendFormat("<td>{0}</td>", item.Order);
				sb.AppendLine("</tr>");
			}
			sb.AppendLine("</table>");

			sb.AppendLine("</body></html>");

			return Content(sb.ToString(), "text/html");

		}


		[ERPStore.Web.Controllers.ActionFilters.AuthorizeActionFilter]
		public ActionResult ShowCacheItemList(int? pageIndex)
		{
			var sb = new StringBuilder();
			if (!pageIndex.HasValue)
			{
				pageIndex = 0;
			}

			var cacheItemCount = CacheService.ItemCount;
			string content = string.Format("Nombre d'item en cache : {0}", cacheItemCount);

			long globalSize = 0;
			foreach (var item in CacheService.GetAllItem())
			{
				try
				{
					globalSize += item.Value.SizeOf();
				}
				catch
				{

				}
			}

			var allItems = CacheService.GetAllItem().Skip(pageIndex.Value * 50).Take(50);
			sb.AppendLine("<html>");
			sb.AppendLine("<body>");

			sb.AppendFormat("<p>{0}</p>", content);
			sb.AppendFormat("<p>Taille estimée : {0:#,##} ko<p>", globalSize / 1024);


			sb.AppendLine("<table>");
			sb.AppendLine("<tr>");
			sb.AppendLine("<td>Type Name</td>");
			sb.AppendLine("<td>Count</td>");
			sb.AppendLine("<td>Size</td>");
			sb.AppendLine("</tr>");

			var typeList = CacheService.GetAllItem().GroupBy(i => i.Value.GetType().Name);
			foreach (var item in typeList)
			{
				long typeSize = 0;
				sb.AppendLine("<tr>");
				sb.AppendFormat("<td>{0}</td>", item.Key);
				sb.AppendFormat("<td>{0}</td>", item.Count());

				foreach (var subitem in item)
				{
					try
					{
						typeSize += subitem.Value.SizeOf();
					}
					catch
					{
					}
				}
				sb.AppendFormat("<td>{0:#,##} ko</td>", typeSize / 1024);
				sb.AppendLine("</tr>");
			}
			sb.AppendLine("</table>");

			sb.AppendLine("<hr>");

			sb.AppendLine("<table>");
			sb.AppendLine("<tr>");
			sb.AppendLine("<td>Key</td>");
			sb.AppendLine("<td>Type Name</td>");
			sb.AppendLine("<td>Expiration Date</td>");
			sb.AppendLine("<td>Expire (s)</td>");
			sb.AppendLine("<td>Size</td>");
			sb.AppendLine("</tr>");
			foreach (var item in allItems)
			{
				sb.AppendLine("<tr>");
				sb.AppendFormat("<td>{0}</td>", item.Key);
				sb.AppendFormat("<td>{0}</td>", item.Value.GetType().Name);
				sb.AppendFormat("<td>{0:yyyy/MM/dd HH:mm:ss}</td>", item.ExpirationDate);
				sb.AppendFormat("<td>{0}</td>", Convert.ToInt32((item.ExpirationDate - DateTime.Now).TotalSeconds));
				try
				{
					sb.AppendFormat("<td>{0}</td>", item.Value.SizeOf());
				}
				catch
				{
					sb.AppendFormat("<td>Not Serializable : {0}</td>", item.Value.ToString());
				}
				sb.AppendLine("</tr>");
			}
			sb.AppendLine("</table>");


			sb.AppendLine("</body>");
			sb.AppendLine("</html>");

			return Content(sb.ToString(), "text/html");
		}

		[ERPStore.Web.Controllers.ActionFilters.AuthorizeActionFilter]
		public ActionResult StartGarbageCollector()
		{
			GC.Collect();
			return Content("done", "text/plain");
		}

		[ERPStore.Web.Controllers.ActionFilters.AuthorizeActionFilter]
		public ActionResult GarbageStats()
		{
			long memorySize = GC.GetTotalMemory(true);
			return Content(memorySize.ToString(), "text/plain");
		}

		[ERPStore.Web.Controllers.ActionFilters.AuthorizeActionFilter]
		public ActionResult ProductStockInfo(string productCode)
		{
			var catalogService = DependencyResolver.Current.GetService<ERPStore.Services.ICatalogService>();
			var stockInfo = catalogService.GetProductStockInfo(productCode);

			var sb = new StringBuilder();

			sb.AppendFormat("AvailableStock :{0}\r\n", stockInfo.AvailableStock);
			sb.AppendFormat("DeliveryDaysCount :{0}\r\n", stockInfo.DeliveryDaysCount);
			sb.AppendFormat("Disponibility :{0}\r\n", stockInfo.Disponibility);
			sb.AppendFormat("HasStock :{0}\r\n", stockInfo.HasStock);
			sb.AppendFormat("MinimalQuantity :{0}\r\n", stockInfo.MinimalQuantity);
			sb.AppendFormat("MostProvisionningDate :{0}\r\n", stockInfo.MostProvisionningDate);
			sb.AppendFormat("PhysicalStock :{0}\r\n", stockInfo.PhysicalStock);
			sb.AppendFormat("ProductCode :{0}\r\n", stockInfo.ProductCode);
			sb.AppendFormat("ProvisionnedQuantity :{0}\r\n", stockInfo.ProvisionnedQuantity);
			sb.AppendFormat("ProvisionningDaysCount :{0}\r\n", stockInfo.ProvisionningDaysCount);
			sb.AppendFormat("ReservedQuantity :{0}\r\n", stockInfo.ReservedQuantity);
			sb.AppendFormat("TotalProvisionningDayCount :{0}\r\n", stockInfo.TotalProvisionningDayCount);

			return Content(sb.ToString(), "text/plain");
		}

		public ActionResult TaskList()
		{
			var sb = new StringBuilder();

			var taskService =  GlobalConfiguration.Configuration.DependencyResolver.GetService<ERPStore.Services.IScheduledTaskService>();

			sb.AppendLine("<html><body>");
			sb.AppendFormat("<p>Tasks {0}</p>", taskService.GetTaskCount());

			sb.AppendLine("<table>");
			sb.AppendLine("<tr>");
			sb.AppendLine("<td>Name</td>");
			sb.AppendLine("<td>Scope</td>");
			sb.AppendLine("<td>Order</td>");
			sb.AppendLine("</tr>");

			sb.AppendLine("</table>");

			sb.AppendLine("</body></html>");

			return Content(sb.ToString(), "text/html");
		}

		[ERPStore.Web.Controllers.ActionFilters.AuthorizeActionFilter]
		public ActionResult TestSmtp(string templateName)
		{
			var emailTemplateService = GlobalConfiguration.Configuration.DependencyResolver.GetService<ERPStore.Web.Services.IEmailTemplateService>();
			var emailService = GlobalConfiguration.Configuration.DependencyResolver.GetService<ERPStore.Services.IEmailerService>();
			var emailTemplate = emailTemplateService.GetTemplate(templateName ?? "test");

			emailService.Send(emailTemplate);

			return Content("done", "text/plain");
		}

		[ERPStore.Web.Controllers.ActionFilters.AuthorizeActionFilter]
		public ActionResult ImageNotFound()
		{
			return View();
		}

		[ERPStore.Web.Controllers.ActionFilters.AuthorizeActionFilter]
		public ActionResult DashBoard()
		{
			return View();
		}

		[ERPStore.Web.Controllers.ActionFilters.AuthorizeActionFilter]
		public ActionResult Partial(string id)
		{
			return PartialView(id);
		}
	}
}
